package com.wocao.admin.business;

import com.wocao.admin.vo.login.LoginVo;
import com.wocao.admin.vo.login.RegisterVo;
import com.wocao.commom.constant.CommonConstant;
import com.wocao.commom.constant.RedisConstant;
import com.wocao.commom.model.UserModel;
import com.wocao.commom.utils.CommonUtil;
import com.wocao.framework.security.utils.JwtTokenUtils;
import com.wocao.system.entity.SysUserDo;
import com.wocao.system.service.RedisService;
import com.wocao.system.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

/**
 * 用户登录业务类
 *
 * @author sunhao
 * @date 2021/8/14
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
@Slf4j
public class SysLoginBusiness {

    // 此处注入的bean在SpringConfig中产生, 如果不在其中声明则注入AuthenticationManager报错
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtTokenUtils jwtTokenUtils;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private RedisService redisService;

    /**
     * 功能描述: 账号登录<br>
     *
     * @param loginVo 账号登录实体
     * @return java.lang.String
     * @author eggg 2021/10/29 14:38
     * @see [相关类/方法]（可选）
     * @since [产品/模块版本]（可选）
     */
    public String login(LoginVo loginVo) {
        Authentication authentication;
        String username = loginVo.getUsername();
        String password = loginVo.getPassword();
        try {
            SysUserDo sysUser = sysUserService.getSysUserByUserName(username);
            if (sysUser == null) {
                throw new UsernameNotFoundException("用户不存在！");
            }
            password = password + sysUser.getSlat();
            // 进行身份验证,
            authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
        } catch (Exception e) {
            throw new UsernameNotFoundException("用户名密码错误！");
        }
        UserModel loginUser = (UserModel) authentication.getPrincipal();
        // 生成token
        String token = jwtTokenUtils.generateToken(loginUser);
        redisService.setex(RedisConstant.SYS_CACHE_TOKEN + token, token, CommonConstant.NUM_1800);
        return token;
    }

    /**
     * 功能描述: 注册接口<br>
     *
     * @param registerVo 账号注册实体
     * @author eggg 2021/8/14 10:56
     * @see [相关类/方法]（可选）
     * @since [产品/模块版本]（可选）
     */
    public String register(RegisterVo registerVo) {
        String username = registerVo.getUsername();
        Boolean exist = sysUserService.checkUserName(username);
        if (exist) {
            return "用户已存在!";
        }
        SysUserDo sysUser = new SysUserDo();
        sysUser.setUsername(username);
        String slat = CommonUtil.randomGen(8);
        String newPassword = bCryptPasswordEncoder.encode(registerVo.getPassword() + slat);
        sysUser.setPassword(newPassword);
        sysUser.setSlat(slat);
        sysUser.setStatus(CommonConstant.NUM_1_STR);
        sysUserService.save(sysUser);
        return null;
    }

    /**
     * 功能描述: 退出接口<br>
     *
     * @param token token
     * @author eggg 2021/8/14 16:06
     * @see [相关类/方法]（可选）
     * @since [产品/模块版本]（可选）
     */
    public void loginOut(String token) {
        if (StringUtils.isEmpty(token)) {
            return;
        }
        redisService.del(RedisConstant.SYS_CACHE_TOKEN + token);
    }

}
